Build Linux dynamic libraries with cross for older glibc compatibility - #1214
Draft
twyatt wants to merge 2 commits into
Draft
Build Linux dynamic libraries with cross for older glibc compatibility#1214twyatt wants to merge 2 commits into
twyatt wants to merge 2 commits into
Conversation
Allows building the dynamic library for a Rust target other than the host's (e.g. cross-compiling aarch64-unknown-linux-gnu from an x86_64 host) and building with a cargo-compatible command such as cross (https://github.com/cross-rs/cross). Co-authored-by: Travis Wyatt <travis.i.wyatt@gmail.com>
GitHub's Ubuntu runners link against a glibc newer than what is available on some Linux distributions (e.g. Raspberry Pi OS), causing JNA to fail to load kable-btleplug-ffi at runtime. Build the Linux dynamic libraries with cross (https://github.com/cross-rs/cross) using its CentOS 7 based images so they link against glibc 2.17, and cross-compile the aarch64 library from the x86_64 runner (cross does not publish arm64 host images). Resolves: #990 Co-authored-by: Travis Wyatt <travis.i.wyatt@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #990
Problem
The Linux
kable-btleplug-ffidynamic libraries are built directly on GitHub's Ubuntu runners, so they link against the runner's glibc (2.38+). On distributions with an older glibc (e.g. Raspberry Pi OS, glibc ≤ 2.36), JNA fails to load the library and Sensortag scans crash immediately.Solution
As suggested in the issue, Linux builds now go through
cross, using its CentOS 7 based images (main-centostags, pinned viakable-btleplug-ffi/Cross.toml) so the produced.sofiles link against glibc 2.17.Note
The issue mentions cross's default toolchain being on glibc 2.31, but cross's default images have since moved to Ubuntu 24.04 (glibc 2.39), which would reproduce the original problem — hence the CentOS 7 images, which the issue also mentions as an option.
uniffi-plugincargoCommandextension property: command used to build the dynamic library (defaults tocargo). CI sets it tocrossfor Linux builds via theUNIFFI_CARGOenvironment variable.targetextension property: Rust target triple to build the dynamic library for (defaults to the host's target). CI sets it via theUNIFFI_TARGETenvironment variable. This was needed because cross does not publish arm64 host images (cross-rs/cross#751), so theaarch64-unknown-linux-gnulibrary is now cross-compiled from the x86_64 runner instead of being built natively onubuntu-24.04-arm.generateKotlinBindingsstill runsuniffi-bindgenwith hostcargo; only the--libraryit parses points at the (possibly cross-compiled) target library, which works since uniffi-bindgen reads metadata from the binary statically.Workflows (
ci.yml/publish.yml)assemble-rustmatrix replaces theubuntu-24.04-arm+ubuntu-latestrunners with twoubuntu-latestentries (one per Linux target) that install cross (from gitmain, matching the pinnedmain-centosimage tags) and exportUNIFFI_CARGO/UNIFFI_TARGET.Local (non-CI) builds are unaffected: without the environment variables set, the plugin behaves exactly as before (
cargo build --target <host triple>).Verification
Performed locally (Docker + cross installed from git main, same as CI):
UNIFFI_CARGO=cross UNIFFI_TARGET=aarch64-unknown-linux-gnu ./gradlew :kable-btleplug-ffi:assemble→ jar containslinux-aarch64/libbtleplug_ffi.so,objdump -Tshows max versioned symbolGLIBC_2.17.UNIFFI_CARGO=cross ./gradlew :kable-btleplug-ffi:cargoBuild(x86_64) → max versioned symbolGLIBC_2.16../gradlew :kable-btleplug-ffi:assemble(no env vars) → unchanged native host build.